/*
 * Copyright (C) 2010, Funcom AS, All Rights Reserved
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  @authors
 *  Svein Gunnar Larsen <sveingunnarlarsen@gmail.com>
 *  Erik Thune Lund <culex.eriklund@gmail.com>
 *  Michel Krohn-Dale <kronicz@gmail.com>
 */

package com.funcom.peeler.peelable;

import com.funcom.peeler.PeelStyleSheet;
import com.jmex.bui.Rule;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.util.Set;

public class PeelerIO {

    public static boolean writePeeledNodesToFile( Document doc, String filename ) {

        try {
            Source source = new DOMSource( doc );

            File file = new File( filename );

            // Wrapped to preserve nice indentation on writePeeledNodesToFile
            StreamResult out = new StreamResult( new OutputStreamWriter( new FileOutputStream( file ) ) );

            TransformerFactory factory = TransformerFactory.newInstance();
            factory.setAttribute( "indent-number", 4 );

            Transformer trans = factory.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.METHOD, "xml");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");
            trans.transform( source, out );

            return true;
        }
        catch ( Exception e ) {
            e.printStackTrace();
            return false;
        }
    }

    public static Document readPeeledNodes( String filename ) {

        Document doc = readPeeledNodesFromFile( filename );

        if ( doc == null ) {
            doc = readPeeledNodesFromResource( filename );
        }

        if ( doc == null ) {
            System.out.println( "Could not load peeled nodes from " + filename );
            return null;
        }

        return doc;
    }

    public static Document readPeeledNodes( InputStream istream ) {

        try {
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( istream );

            if ( doc == null ) {
                System.out.println( "Could not load banana peel from " + istream );
            }

            return doc;
        }
        catch ( IOException e ) {
            System.out.println( e );
            e.printStackTrace();
        }
        catch ( ParserConfigurationException e ) {
            System.out.println( e );
            e.printStackTrace();
        }
        catch ( SAXException e ) {
            System.out.println( e );
            e.printStackTrace();
        }

        return null;
    }

    public static Document readPeeledNodesFromFile( String filename ) {

        try {
            // General setup to load the xml file
            File file = new File( filename );
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( file );
            doc.getDocumentElement().normalize();
            return doc;

        }
        catch ( Exception e ) {
            return null;
        }
    }

    public static Document readPeeledNodesFromResource( String filename ) {

        try {
            InputStream input = PeelerIO.class.getResourceAsStream( filename );
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( input );
            return doc;

        } catch ( Exception e ) {
            return null;
        }
    }

    public static boolean writeStyleSheetToFile( PeelStyleSheet stylesheet, String filename ) {

    String out = StyleSheetExporter.exportStyleSheet( stylesheet );
        return writeFile( out, filename );
    }

    public static boolean writeStyleRulesToFile( Set< Rule > rules, String filename ) {

        if ( rules == null ) return false;
        if ( filename == null ) return false;

        String out = new String();
        out += StyleSheetExporter.exportRules( rules );

        return writeFile( out, filename );
    }

    // Utility method for overwriting a new file
    private static boolean writeFile( String out, String filename ) {

        try {
            BufferedWriter writer = new BufferedWriter( new FileWriter( filename ) );
            writer.write( out );
            writer.close();
            return true;
        }
        catch ( Exception e ) {
            e.printStackTrace();
            return false;
        }
    }
}
